import 'dart:async';
import 'dart:convert';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_member/model/DataEntity.dart';
import 'package:flutter_member/widget/im/message_image.dart';
import 'package:flutter_member/widget/im/message_item.dart';
import 'package:flutter_member/widget/im/message_text.dart';
import 'package:flutter_member/widget/im/unfold_sel_widget.dart';
import 'package:image_picker/image_picker.dart';
import 'package:tencent_im_plugin/entity/session_entity.dart';
import 'package:tencent_im_plugin/tencent_im_plugin.dart';
import 'package:tencent_im_plugin/entity/user_info_entity.dart';
import 'package:tencent_im_plugin/entity/group_info_entity.dart';
import 'package:tencent_im_plugin/entity/message_entity.dart';
import 'package:tencent_im_plugin/enums/message_node_type.dart';
import 'package:tencent_im_plugin/enums/image_type.dart';
import 'package:tencent_im_plugin/message_node/message_node.dart';
import 'package:tencent_im_plugin/message_node/text_message_node.dart';
import 'package:tencent_im_plugin/message_node/image_message_node.dart';

/// 聊天页面
class ImPage extends StatefulWidget {

  /// 会话ID
  final String id;

  /// 会话类型
  final SessionType type;

  const ImPage({
    Key key,
    this.id,
    this.type,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => ImPageState();
}

class ImPageState extends State<ImPage> {

//  选择图片面板
  bool unfold = false;
  /// 刷新加载器
  GlobalKey<RefreshIndicatorState> refreshIndicator = GlobalKey();

  /// 滚动控制器
  ScrollController scrollController = ScrollController();

  TextEditingController controller = TextEditingController();

  /// 用户信息对象
  UserInfoEntity userInfo;

  /// 获取当前登录用户的UserInfoEntity
  UserInfoEntity loginUserInfo;

  /// 群信息对象
  GroupInfoEntity groupInfoEntity;

  /// 当前消息列表
  List<DataEntity> data = [];
  /// 输入框焦点
  FocusNode _commentFocus = FocusNode();
  /// 用作显示提示框
  GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey();
  ScrollController _scrollController;

  @override
  initState() {
    super.initState();
    /// 监听输入框是否获得焦点
    _commentFocus.addListener((){
      if(_commentFocus.hasFocus==true){
        setState(() {
          unfold=false;
        });
      }
    });
    _scrollController = ScrollController();
    init();

    // 获得当前登录用户
    TencentImPlugin.getSelfProfile().then((data) {
      this.setState(() {
        loginUserInfo = data;
      });
    });

    // 获取对话信息
    if (widget.type == SessionType.Group) {
      TencentImPlugin.getGroupInfo(id: widget.id).then((data) {
        this.setState(() {
          groupInfoEntity = data;
        });
      });
    } else if (widget.type == SessionType.C2C) {
      TencentImPlugin.getUserInfo(id: widget.id).then((data) {
        this.setState(() {
          userInfo = data;
        });
      });
    }

    // 获得消息列表
    SchedulerBinding.instance.addPostFrameCallback((_) {
      // 读取缓存
      TencentImPlugin.getLocalMessages(
        sessionId: widget.id,
        sessionType: widget.type,
        number: 30,
      ).then((res) {
        resetData(res);
      });

      refreshIndicator.currentState.show();
    });

    // 添加监听器
    TencentImPlugin.addListener(listener);
  }

  @override
  dispose() {
    super.dispose();
    TencentImPlugin.removeListener(listener);
    _commentFocus.dispose();
    controller.dispose();
    // 取消计数器
//    stopTimer();
    _scrollController.dispose();
  }

  /// 初始化
  init() async {
//    Map<PermissionGroup, PermissionStatus> permissions =
//    await PermissionHandler().requestPermissions([
//      PermissionGroup.storage,
//      PermissionGroup.storage,
//      PermissionGroup.microphone
//    ]);
  }

  /// 监听器
  listener(type, params) {
    // 新消息时更新会话列表最近的聊天记录
    if (type == ListenerTypeEnum.NewMessages) {
      onRefresh();
      // 更新消息列表
      this.setState(() {
        data.add(DataEntity(data: params));
      });
      // 设置已读
      TencentImPlugin.setRead(sessionId: widget.id, sessionType: widget.type);
    }

    // 消息上传通知
    if (type == ListenerTypeEnum.UploadProgress) {
      Map<String, dynamic> obj = jsonDecode(params);

      // 获得进度和消息实体
      int progress = obj["progress"];
      MessageEntity message = MessageEntity.fromJson(obj["message"]);

      // 更新数据
      this.updateData(DataEntity(
        data: message,
        progress: progress,
      ));
    }
  }

  /// 发送事件
  onSend() async {
    if (controller.text == null || controller.text.trim() == "") {
      Scaffold.of(context).showSnackBar(SnackBar(
          content: Text('不能发送空值!'), duration: Duration(milliseconds: 2000)));
      return;
    }

    this.sendMessage(
      TextMessageNode(
        content: controller.text,
      ),
      MessageText(text: controller.text),
    );

    controller.text = "";

    Timer(
        Duration(milliseconds: 200),
            () =>
            scrollController.jumpTo(scrollController.position.maxScrollExtent));
  }

  /// 获取消息列表事件
  Future<void> onRefresh() {
    return TencentImPlugin.getMessages(
      sessionId: widget.id,
      sessionType: widget.type,
      number: data.length + 30,
    ).then((res) {
      resetData(res);
      // 设置已读
      TencentImPlugin.setRead(sessionId: widget.id, sessionType: widget.type);
    });
  }

  /// 更新显示的数据
  resetData(List<MessageEntity> messageEntity) {
    this.data = [];
    for (var item in messageEntity) {
      this.updateData(DataEntity(data: item));
    }

    scrollController.jumpTo(scrollController.position.maxScrollExtent);
  }

  /// 更新单个数据
  updateData(DataEntity dataEntity) {
    bool exist = false;
    for (var index = 0; index < data.length; index++) {
      DataEntity item = data[index];
      if (item.data == dataEntity.data) {
        this.data[index] = dataEntity;
        exist = true;
        break;
      }
    }

    if (!exist) {
      this.data.add(dataEntity);
    }

    this.setState(() {});
    scrollController.jumpTo(scrollController.position.maxScrollExtent);
  }

  /// 获得组件
  getComponent(MessageEntity message) {
    List<MessageNode> elems = message.elemList;
    if (elems == null || elems.length == 0) {
      return Text("");
    }
    // 只取第一个
    var node = elems[0];
    if (node == null) {
      return null;
    }
    switch (node.nodeType) {
      case MessageNodeType.Text:
        TextMessageNode value = node;
        return MessageText(text: value.content);
      case MessageNodeType.Image:
        ImageMessageNode value = node;
        print(value.imageData[ImageType.Large]?.url);
        return MessageImage(
            url: value.imageData[ImageType.Thumb]?.url);
      case MessageNodeType.GroupTips:
        return MessageText(text: "[群提示节点，未指定解析规则]");
      case MessageNodeType.Other:
      case MessageNodeType.SnsTips:
        break;
      case MessageNodeType.GroupSystem:
        break;
      case MessageNodeType.ProfileSystem:
        break;
    }
    return MessageText(text: "[不支持的消息节点]");
  }

  //<editor-fold desc="控件的相应事件">

  /// 选择图片
  onSelectImage({camera=false}) async {
    var image = await ImagePicker.pickImage(source: camera==true?ImageSource.camera:ImageSource.gallery);
    if (image != null) {
      this.sendMessage(
        ImageMessageNode(
          path: image.path,
        ),
        MessageImage(
          path: image.path,
        ),
      );
    }
  }

  /// 发送消息
  sendMessage(node, wd) {
    TencentImPlugin.sendMessage(
      sessionId: widget.id,
      sessionType: widget.type,
      node: node,
    ).then((res) {
      this.setState(() {
        this.updateData(DataEntity(data: res));
      });
    }).catchError((e) {
      _scaffoldKey.currentState
          .showSnackBar(SnackBar(content: new Text('消息发送失败:$e')));
    });
  }
  //</editor-fold>

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      key: _scaffoldKey,
      appBar:MyAppBar(userInfo != null
          ? userInfo.nickName : (groupInfoEntity != null
          ? "${groupInfoEntity.groupName}(${groupInfoEntity.memberNum})"
          : "")),

      body:GestureDetector(
        onTap: (){
          setState(() {
            _commentFocus.unfocus();
            if(unfold==true){
              unfold=false;
            };
          });
        },
        child: Container(
          color: Colors.white,
          child: Column(
            children: <Widget>[
              Expanded(
                child: RefreshIndicator(
                  onRefresh: onRefresh,
                  key: refreshIndicator,
                  child: ListView(
                    controller: scrollController,
                    children: List.generate(
                      data.length, (index) => LayoutBuilder(
                      builder:
                          (BuildContext context, BoxConstraints constraints) {
                        return GestureDetector(
                          child: MessageItem(
                            data: data[index],
                            child: getComponent(data[index].data),
                          ),
                        );
                      },
                    ),
                    ),
                  ),
                ),
              ),
              Stack(
                children: <Widget>[
                  Container(
                    height: 68,
                    decoration: BoxDecoration(
                        color: Color(0xffE5EEF6),
                        borderRadius: BorderRadius.all(Radius.circular(25))
                    ),
                  ),
                  Container(
                    height: 60,
                    decoration: BoxDecoration(
                        borderRadius: BorderRadius.only(topLeft: Radius.circular(25),topRight: Radius.circular(25)),
                        color: Colors.white
                    ),
                    padding: EdgeInsets.only(left: 15,right: 15,),
                    margin: EdgeInsets.only(top: 8),
                    child:  Row(
                      children: <Widget>[
                        InkWell(
                          onTap: (){
                            setState(() {
                              unfold=!unfold;
                              _commentFocus.unfocus();
                            });
                          },
                          child: Container(
                            child: ImageIcon(
                              AssetImage("images/new.png"),
                              color: Color(0xff3d6fc1),
                            ),
                            padding: EdgeInsets.only(left: 5, right: 10),
                          ),
                        ),
                        Expanded(
                          child: new ConstrainedBox(
                            constraints: BoxConstraints(
                              maxHeight: 45,
                            ),
                            child: new TextField(
                              controller: controller,
                              focusNode: _commentFocus,
                              decoration: InputDecoration(
                                contentPadding:
                                const EdgeInsets.symmetric(vertical: 4.0),
                                // contentPadding: EdgeInsets.all(10),
                                border: OutlineInputBorder(
                                    borderRadius: BorderRadius.circular(30),
                                    borderSide: BorderSide.none),
                                filled: true,
                                fillColor: Color(0xffF6F6F6),
                              ),
                            ),
                          ),
                        ),
                        Container(
                          padding: EdgeInsets.only(left: 10),
                          child: ImageButton(image: "images/send.png"),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
              unfold ? Container(
                height: 250,
                padding: EdgeInsets.only(left: 50,top: 20),
                color: Colors.white,
                child: Row(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: <Widget>[
                    UnfoldSelWidget(
                      image: "images/album-2.png",
                      title: "相簿",
                      onPressed: ()=>onSelectImage(camera: false),
                    ),
                    UnfoldSelWidget(
                      image: "images/camera.png",
                      title: "拍照",
                      onPressed: ()=> onSelectImage(camera: true),
                    )
                  ],
                ),
              ) : Container(),
            ],
          ),
        ),
      ),
    );
  }

  Widget MyAppBar(String title){
    return PreferredSize(

      child: Stack(
        children: <Widget>[
          Container(
            padding: EdgeInsets.only(left: 10, top: 10),
            width: double.infinity,
            height: 130,
            decoration: BoxDecoration(
                color: Color(0xffE5EEF6),
                borderRadius: BorderRadius.only(
                    bottomLeft: Radius.circular(25),
                    bottomRight: Radius.circular(25))),
          ),
          Container(
            padding: EdgeInsets.only(left: 10),
            width: double.infinity,
            height: 120,
            decoration: BoxDecoration(
                color: Color(0xff2D7FC7),
                borderRadius: BorderRadius.only(
                    bottomLeft: Radius.circular(25),
                    bottomRight: Radius.circular(25))),
            child: SafeArea(
                child: Stack(
                  children: <Widget>[
                    IconButton(
                      color: Color(0xffffffff),
                      icon: Icon(Icons.arrow_back),
                      onPressed: () {
                        Navigator.pop(context);
                      },
                      iconSize: 30,
                    ),
                    Center(
                      child: Text(
                        title,
                        style: TextStyle(
                            color: Color(0xffffffff),
                            fontSize: 20,
                            fontWeight: FontWeight.w500),
                        textAlign: TextAlign.center,
                      ),
                    )
                  ],
                )),
          ),
        ],
      ),
      preferredSize: Size(double.infinity, 90),
    );
  }

  Widget ImageButton({@required String image}) {
    return InkWell(
      child: Image.asset(
        image,
        height: 35,
        width: 35,
      ),
      onTap:onSend,
    );
  }
}